package tp.model;

import java.awt.Component;
import java.awt.event.KeyEvent;
import java.util.*;
import tp.model.Misil;
import tp.controller.Controlador;
import tp.view.NaveView;

public class Nave extends Observable implements Chocable {

	private Posicion MiPosicion;

	public NaveView miVista;
	
	private ComportamientoDisparar CompDisp;

	private Posicion MiDireccion;

	private double MiAltura;

	private double MiAncho;

	private Bola bola;

	private boolean Pegajosa;

	private boolean Misilera = false;

	private boolean triBola = false;

	private Posicion MiPosicionVieja;

	private double MiRadio = 1;

	private boolean Doble;

	private boolean velocidad = false;

	private boolean BolaDeFuego = false;// momentaneamente

	private boolean Disparar = false;

	private boolean bolaDebil = false;

	private boolean vivo = true;
	
	private boolean left = false;
	
	private boolean right = false;
	
	private int vx = 0;
	
	private int vy = 0;

	public Nave(Posicion pos1, Posicion pos2) {

		this.setMiPosicion(pos1);
		this.setMiDireccion(pos2);
		this.setMiAltura(18);
		this.setMiAncho(100);
		Controlador.controlador.addChocable(this);
		Controlador.controlador.setNave(this);
		// CopyOfBoardView1.addVisible(new NaveView(this));
		miVista = new NaveView(this);
		CompDisp = new ExpulsarBola();
		//
	}

	public void setMiPosicion(Posicion P) {
		this.MiPosicion = P;
	}

	public Posicion getMiPosicion() {
		return this.MiPosicion;
	}

	public double getMiAltura() {
		return MiAltura;
	}

	public void setMiAltura(double miAltura) {
		this.MiAltura = miAltura;
	}

	public double getMiAncho() {
		return MiAncho;
	}

	public void setMiAncho(double miAncho) {
		this.MiAncho = miAncho;
	}

	public Posicion getMiDireccion() {
		return MiDireccion;
	}

	public void setMiDireccion(Posicion miDireccion) {
		this.MiDireccion = miDireccion;
	}

	public boolean meToca(Chocable elem) {
		Posicion posChocador = elem.getMiPosicion();
		if ((posChocador.getY() <= ((this.getMiPosicion().getY()) + (this
				.getMiAltura() / 2)))
				&& (posChocador.getY() >= ((this.getMiPosicion().getY()) - (this
						.getMiAltura() / 2)))) {
			if ((posChocador.getX() <= ((this.getMiPosicion().getX()) + (this
					.getMiAncho() / 2)))
					&& (posChocador.getX() >= ((this.getMiPosicion().getX()) - (this
							.getMiAncho() / 2)))) {
				return true;
			}
			return false;
		}
		return false;
	}

	public boolean meToca(Posicion pos) {
		if ((pos.getX() > (this.MiPosicion.getX() - this.MiAncho / 2) && (pos
				.getX() < (this.MiPosicion.getX()) + this.MiAncho / 2))) {
			if ((pos.getY() > (this.MiPosicion.getY() - this.MiAltura / 2) && (pos
					.getY() < (this.MiPosicion.getY()) + this.MiAltura / 2))) {
				return true;
			}
		}
		return false;
	}

	public Posicion dondeMeToca(Chocable elem) {
		Posicion lado;
		lado = new Posicion(this.getMiPosicion().getX(), this.getMiPosicion()
				.getY()
				+ (this.getMiAltura() / 2));
		lado = elem.getMiPosicionVieja().moverEnYEnDireccion(lado,
				elem.getMiDireccion());// Va a obtener la posicion de interseccion
		if ((this.MiPosicion.getX() - (this.getMiAncho() / 2) < lado.getX())&& (this.MiPosicion.getX() + (this.getMiAncho() / 2) > lado.getX())) {
			return lado;
		}
		lado.setPosicion(this.getMiPosicion().getX() + (this.getMiAncho() / 2),this.getMiPosicion().getY());
		lado = elem.getMiPosicionVieja().moverEnXEnDireccion(lado,
				elem.getMiDireccion());
		if ((lado.getY() < this.getMiPosicion().getY()
				+ (this.getMiAltura() / 2))
				&& (lado.getY() > this.getMiPosicion().getY()
						- (this.getMiAltura() / 2))) {
			return lado;
		}
		lado.setPosicion(this.getMiPosicion().getX() - (this.getMiAncho() / 2),
				this.getMiPosicion().getY());
		lado = elem.getMiPosicionVieja().moverEnXEnDireccion(lado,
				elem.getMiDireccion());
		if ((lado.getY() < this.getMiPosicion().getY()
				+ (this.getMiAltura() / 2))
				&& (lado.getY() > this.getMiPosicion().getY()
						- (this.getMiAltura() / 2))) {
			return lado;
		}
		return null;
	}
	
	public Posicion hago() {
		double x = this.getMiPosicion().getX() + vx;
		double y = this.getMiPosicion().getY() + vy;
		Posicion P = new Posicion(x,y);
		this.setMiPosicion(P);
		return P;
	}


	  

	public Posicion getMiPosicionVieja() {
		return this.MiPosicionVieja;
	}

	public void meChocaron(Chocable elem) {
		if (this.Pegajosa == true) {
			if ((elem instanceof Bola) && (null == this.getBola())) {
				// si el elemento es bola y si no tiene ya una bola pegada
				bola = (Bola) elem;
				bola.setVelocidad(0);
			}
		}
	}

	public Posicion miNormal(Chocable elem) {
		/*
		 * Nave transitorio = new Nave(elem.getMiPosicionVieja(),
		 * elem.getMiDireccion());
		 * transitorio.setMiDireccion(elem.getMiDireccion());
		 * transitorio.setMiPosicionVieja(elem.getMiPosicionVieja());
		 */
		Posicion pos1 = this.dondeMeToca(elem);// transitorio fue remplazado
												// por elem
		if (pos1.getY() == (this.getMiPosicion().getY() + (this.getMiAltura() / 2))) {
			return new Posicion(0, 1);
		}
		if (pos1.getX() == (this.getMiPosicion().getX() + (this.getMiAncho() / 2))) {
			return new Posicion(1, 0);
		}
		if (pos1.getX() == (this.getMiPosicion().getX() - (this.getMiAncho() / 2))) {
			return new Posicion(-1, 0);
		}
		return null;
	}

	public void setMiDireccion(double x, double y) {
		this.MiDireccion.setPosicion(x, y);

	}

	public void setMiPosicionVieja(Posicion pos1) {
		this.MiPosicionVieja = pos1;

	}

	public String getClase() {
		return "Nave";
	}

	/**
	 * se mueve mientras este en el limite permitido por el entorno (enviroment)
	 * 
	 * @param limitIzq
	 *            es un chocable que le propina el limite izquierdo
	 */
	public void moverEnXIzquierda(int limitIzq) {
		if ((this.getMiPosicion().getX() - (this.getMiAncho() / 2)) > limitIzq - 2) {// el
			// (-2)
			// es
			// arbitrario // puede
			// ser cualquier valor razonable
			this.MiPosicionVieja = this.MiPosicion;
			this.MiPosicion = (this.getMiPosicion()
					.sumarPosicionX(-Controlador.velNave));
			if (bola != null)
				bola.moverEnXIzquierda(limitIzq);
		}
	}

	/**
	 * se mueve mientras este en el limite permitido por el entorno (enviroment)
	 * 
	 * @param limitDer
	 *            es un chocable que le propina el limite derecho
	 */
	public void moverEnXDerecha(int limitDer) {
		if ((this.getMiPosicion().getX() + (this.getMiAncho() / 2)) < limitDer + 2) {
			this.MiPosicionVieja = this.MiPosicion;
			this.MiPosicion = (this.getMiPosicion()
					.sumarPosicionX(Controlador.velNave));
			if (bola != null)
				bola.moverEnXDerecha(limitDer);
		}
	}

	public void expulso() {
		this.CompDisp.expulsar(bola, Controlador.controlador, this);
	}

	public boolean isVivo() {
		// TODO Auto-generated method stub
		return true;
	}

	/**
	 * @return the miRadio
	 */
	public double getMiRadio() {
		return MiRadio;
	}

	/**
	 * @param miRadio
	 *            the miRadio to set
	 */
	public void setMiRadio(double miRadio) {
		MiRadio = miRadio;
	}

	public Bola getBola() {
		return bola;
	}

	public void setBola(Bola bola) {
		this.bola = bola;
	}

	public void revertirPoderes() {
		if (this.isVelocidad())
			this.revertVelocidad();
		if (this.Pegajosa)
			revertPegajosa();
		if (this.Misilera){
			Misilera = false;
			this.CompDisp = new ExpulsarBola();
		}
		if (this.isBolaDeFuego())
			revertBolaDeFuego();
		if (this.Doble)
			revertDoble();
		if (this.bolaDebil)
			revertBolaDebil();
		if (this.triBola)
			this.setTriBola(false);
	}

	public boolean isMisilera() {
		return Misilera;
	}

	public void setMisilera() {
		if (isMisilera() == false) {
			this.revertirPoderes();
			Misilera = true;
			this.CompDisp = new ExpulsarBolayMisil();
		}
	}

	public void revertMisilera() {
		if (Misilera) {
			Misilera = false;
			this.CompDisp = new ExpulsarBola();
		}
	}

	public void revertPegajosa() {
		if (Pegajosa) {
			Pegajosa = false;
		}
	}

	public void setPegajosa() {
		if (Pegajosa == false) {
			this.revertirPoderes();
			Pegajosa = true;
		}
	}

	public boolean isTriBola() {
		return triBola;
	}

	public void setTriBola(boolean tri) {
		if (tri) {
			this.revertirPoderes();
			if (Controlador.controlador.CantBolas < 3) {
				new Bola().setVelocidad(Controlador.velBola);
				if (Controlador.controlador.CantBolas == 1) {
					Bola a = new Bola();
					a.setMiPosicion(a.getMiPosicion().sumarPosicionY(20));
					a.setVelocidad(Controlador.velBola);
				}
				Controlador.controlador.CantBolas = 3;
			}
		}
	}

	public void setDoble(boolean b) {
		if (!Doble) {
			this.revertirPoderes();
			this.MiPosicion = this.MiPosicion.sumarPosicionY(this.MiAltura
					* (1 / 4));
			this.MiAncho = this.getMiAncho() * (1.5);
			this.MiAltura = this.getMiAltura() * (1.2);
			Doble = true;
		}
	}

	public void revertDoble() {
		if (Doble) {
			this.MiPosicion = this.MiPosicion.sumarPosicionY(-this.MiAltura
					* (1 / 6));
			this.MiAncho = this.getMiAncho() / (1.5);
			this.MiAltura = this.getMiAltura() / (1.2);
		}
		Doble = false;
	}

	public boolean isVelocidad() {
		return velocidad;
	}

	public void setVelocidad() {
		if (!isVelocidad()) {
			this.revertirPoderes();
			Iterator <Chocable> it = Controlador.controlador.ListaChocables.iterator();
			while (it.hasNext()) {
				Chocable elem = (Chocable) it.next();
				if (elem.getClase() == "Bola") {
					((Bola) elem).MiVelocidad = ((Bola) elem).MiVelocidad / 2;
				}
			}
			velocidad = true;
		}
	}

	public void revertVelocidad() {
		if (isVelocidad()) {
			Iterator <Chocable> it = Controlador.controlador.ListaChocables.iterator();
			while (it.hasNext()) {
				Chocable elem = (Chocable) it.next();
				if (elem.getClase() == "Bola") {
					((Bola) elem).MiVelocidad = ((Bola) elem).MiVelocidad * 2;
				}
			}
		}
		velocidad = false;
	}

	private boolean isBolaDeFuego() {
		return BolaDeFuego;
	}

	public void setVivo(boolean b) {
		this.vivo = true;
	}

	public Component getMiVista() {
		return miVista;
	}

	public void setBolaDeFuego() {
		if (!isBolaDeFuego()) {
			this.revertirPoderes();
			BolaDeFuego = true;
		}
	}

	public void revertBolaDeFuego() {
		if ((isBolaDeFuego()) && (Controlador.getCantBolas() > 0)) {
			Iterator <Chocable> it = Controlador.controlador.ListaChocables.iterator();
			boolean encontrado = false;
			while (it.hasNext() && !encontrado) {
				Chocable choc = (Chocable) it.next();
				if (choc.getClase() == "BolaDeFuego") {
					encontrado = true;
					Bola bolaaux = new Bola();
					bolaaux.setMiPosicion(choc.getMiPosicion());
					bolaaux.setMiDireccion(choc.getMiDireccion().getX(), choc
							.getMiDireccion().getY());
					bolaaux.setMiPosicionVieja(choc.getMiPosicionVieja());
					bolaaux.setVelocidad(((BolaDeFuego) choc).getVelocidad());
					choc.setVivo(false);
					if (this.getBola() != null) {
						this.setBola(bolaaux);
					}
				}
			}
			BolaDeFuego = false;
		}
	}

	public boolean canDisparar() {
		return Disparar;
	}

	public void setDisparar(boolean b) {
		Disparar = b;
	}

	public void setBolaDebil() {
		if (this.bolaDebil == false) {
			this.revertirPoderes();
			Iterator it = Controlador.controlador.ListaChocables.iterator();
			while (it.hasNext()) {
				Chocable choc = (Chocable) it.next();
				if (choc.getClase() == "Ladrillo") {
					((Ladrillo) choc).setVida(((Ladrillo) choc).getVida() * 2);
				}
			}
			this.bolaDebil = true;
		}
	}

	public void revertBolaDebil() {
		if (this.bolaDebil == true) {
			Iterator it = Controlador.controlador.ListaChocables.iterator();
			while (it.hasNext()) {
				Chocable choc = (Chocable) it.next();
				if (choc.getClase() == "Ladrillo") {
					if (((Ladrillo) choc).getVida() > 1) {
						int vida = (int) Math
								.ceil(((Ladrillo) choc).getVida() / 2);
						((Ladrillo) choc).setVida(vida);
					}
				}
			}
			this.bolaDebil = false;
		}
	}
}